package cn.iocoder.yudao.module.trade.service.order.handler;

import cn.iocoder.yudao.framework.common.enums.trade.TradeOrderStatusEnum;
import cn.iocoder.yudao.framework.common.enums.trade.TransactionTypeEnum;
import cn.iocoder.yudao.framework.common.exception.util.ServiceExceptionUtil;
import cn.iocoder.yudao.module.member.api.config.dto.MemberConfMaterialDTO;
import cn.iocoder.yudao.module.member.api.config.dto.MemberConfRespDTO;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderCreateReqDTO;
import cn.iocoder.yudao.module.pay.api.order.dto.PayOrderRespDTO;
import cn.iocoder.yudao.module.pay.enums.notify.PayNotifyTypeEnum;
import cn.iocoder.yudao.module.trade.controller.app.order.vo.AppTradeOrderOrderReqVO;
import cn.iocoder.yudao.module.trade.dal.dataobject.order.TradeOrderDO;
import cn.iocoder.yudao.module.trade.enums.delivery.DeliveryTypeEnum;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateReqBO;
import cn.iocoder.yudao.module.trade.service.price.bo.TradePriceCalculateRespBO;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;

import static cn.iocoder.yudao.module.trade.enums.ErrorCodeConstants.ORDER_CREATE_FAIL_USER_NO_PERMISSION;

/**
 * 锁价交易模式处理器
 */
@Component
public class PriceLockBuyTransactionHandler extends AbstractTransactionModeHandler {

    private static final TransactionTypeEnum TRANSACTION_TYPE = TransactionTypeEnum.PRICE_LOCK_BUY;

    @Override
    public Integer getTransactionType() {
        return TRANSACTION_TYPE.getType();
    }

    @Override
    public void validatePermission(MemberConfRespDTO memberConf) {
        if (Boolean.FALSE.equals(memberConf.getFullPayBuy())) {
            throw ServiceExceptionUtil.exception(ORDER_CREATE_FAIL_USER_NO_PERMISSION, TRANSACTION_TYPE.getDesc());
        }
    }
    
    @Override
    public void validateTradeLimits(MemberConfMaterialDTO materialConf, AppTradeOrderOrderReqVO settlementReqVO) {
        // 调用父类的通用限制校验
        super.validateTradeLimits(materialConf, settlementReqVO);
        
//        // 锁价交易特有的限制校验
//        if (materialConf.getPriceLockLimit() != null &&
//            settlementReqVO.getPrice().compareTo(materialConf.getPriceLockLimit()) > 0) {
//            throw ServiceExceptionUtil.exception(ORDER_CREATE_FAIL_PRICE_LOCK_LIMIT_EXCEEDED);
//        }
    }

    @Override
    protected void setPriceResult(TradePriceCalculateReqBO calculateReqBO, TradePriceCalculateRespBO result, TradePriceCalculateRespBO context) {
        if (context.getDeposit().compareTo(BigDecimal.ZERO) > 0) {
            result.setPayType(PayNotifyTypeEnum.ORDER_DEPOSIT.getType());
        } else {
            result.setPayType(PayNotifyTypeEnum.ORDER.getType());
        }
        result.setDeposit(context.getDeposit());
//        result.setTotalPrice(context.getMetalPrice());
    }

    @Override
    protected BigDecimal calculatePayPrice(TradePriceCalculateReqBO calculateReqBO, TradePriceCalculateRespBO calContext) {
        return calContext.getDeposit();
    }

    @Override
    public PayOrderCreateReqDTO creatSettlePay(TradeOrderDO order, Boolean isViolate) {
        PayOrderCreateReqDTO payOrder = super.initPayOrderCreate(order.getOrderNo());
        // 已支付单
        PayOrderRespDTO payOrderRespDTO = payOrderApi.getOrder(order.getPayOrderId());
        // 现价
        BigDecimal livePriceSell = livePriceApi.getConfPrice(order.getMetalType(), true);

        /*
            违约结算: 
            不用在支付任何费用(需要保证结算时定金率>=20% ) 
            正常结算:
            应支付= 净金价 + (延期费-已交延期费) + (工费-已交工费) + (附加费 - 已交附加费) - 已交定金
        */

        // 1.需补定金 = 基础定金 + (当前价格-下单价格) * weight / 定金参数 * 10 - 已交定金 （一般是定金不足的情况下需要计算）
        BigDecimal depositFee = super.calculateDeposit(order.getWeight(), order.getDepositPriceConf(),
                 order.getOrderPrice(), livePriceSell, payOrderRespDTO.getDeposit());
        // 2. 净金价
        BigDecimal metalPrice = order.getMetalPrice();

        // 3.延期费 = （当前日期 - 下单日期 - 免息天数 ） * 延期费配置  - 已交延期费
        BigDecimal delayFee = super.calculateDelayPrice(order.getCreateTime(), order.getInterestFreeDays(),
                payOrderRespDTO.getDelayPrice(), order.getDelayFeeConf(), order.getWeight());

        // 4.工费 = （克重 * 工费配置） - 已交工费
        BigDecimal processFee = super.calculateProducePrice(order.getWeight(), order.getProcessConf(), payOrderRespDTO.getProcessPrice());

        // 5.附加费 = 附加费 - 已交附加费

        // 服务费
        BigDecimal price = depositFee.add(delayFee).add(processFee);

        // 违约结算
        if (isViolate) {
            payOrder.setIsViolate(true);
            payOrder.setPayType(PayNotifyTypeEnum.SETTLE_BOOM.getType());
            // 多的定金退回?
            if (price.compareTo(BigDecimal.ZERO) < 0) {
                payOrder.setPrice(BigDecimal.ZERO);
            } else {
                payOrder.setDelayPrice(delayFee);
                payOrder.setProcessPrice(processFee);
                payOrder.setDeposit(depositFee);
                payOrder.setPrice(price);
            }
            return payOrder;
        }
        // 正常结算 定金在结清后退回
//        payOrder.setDeposit(BigDecimal.ZERO.subtract(payOrderRespDTO.getDeposit()));   // 退定金:支付的定金清0
        payOrder.setDelayPrice(delayFee);
        payOrder.setProcessPrice(processFee);
//        payOrder.setAdditionalPrice();
        payOrder.setPrice(metalPrice.add(delayFee).add(processFee)
//                .subtract(payOrderRespDTO.getDeposit())
        );
        return payOrder;
    }

    /*
     * 锁价模式:多次付款
     *
     */
    @Override
    public TradeOrderStatusEnum getNextStatusBySuceess(TradeOrderDO order, Integer payType, Boolean isStore) {
        TradeOrderStatusEnum nowStatus = TradeOrderStatusEnum.getEnum(order.getStatus());
        // TODO: 2025/3/27 无实物结算，生成结算单按照直接买卖
        if (PayNotifyTypeEnum.isSettle(payType)) {
            if (PayNotifyTypeEnum.SETTLE_BOOM.getType().equals(payType)) {
                return TradeOrderStatusEnum.CLOSED;
            }
//            if (PayNotifyTypeEnum.SETTLE_ORDER.getType().equals(payType)) {
//                return TradeOrderStatusEnum.PREPARE;
//            }
//            return TradeOrderStatusEnum.SETTLED;
        }

        // 正常结算
        switch (nowStatus) {
            case UNPAID -> {
                if (!PayNotifyTypeEnum.SETTLE_ORDER.getType().equals(payType)) {
                    return TradeOrderStatusEnum.PART_PAID;
                }
                return TradeOrderStatusEnum.UNPAID;
            }
            case PART_PAID, SETTLING, WAIT_PAY_CHECK -> {
                if (isStore) {
                    return TradeOrderStatusEnum.COMPLETED;
                }
                if (PayNotifyTypeEnum.SETTLE_ORDER.getType().equals(payType)) {
                    return TradeOrderStatusEnum.PREPARE;
                }
            }
            case PREPARE -> {
                return TradeOrderStatusEnum.PREPARE_DONE;
            }
            case PREPARE_DONE -> {
                if (DeliveryTypeEnum.PICK_UP.getType().equals(order.getDeliveryType())) {
                    return TradeOrderStatusEnum.COMPLETED;
                }
                return TradeOrderStatusEnum.DELIVERED;
            }
            case DELIVERED -> {
                return TradeOrderStatusEnum.COMPLETED;
            }

        }
        return null;
    }


} 